/* SPDX-License-Identifier: GPL-2.0-or-later */
#include <limits>
#include <climits>
#include <cmath>

#include "Graphics.hpp"
#include "font8x8.hpp"


Graphics::Graphics(uint32_t* buffer, int width, int height) {
	this->buffer = buffer;
	this->width = width;
	this->height = height;
}

Graphics::~Graphics() {
}

void Graphics::plot (int x, int y, uint32_t mask, uint32_t color) {
	if (x < 0 || y < 0 || x >= width || y >= height) {
		return;
	}
	int i = y * width + x;
	buffer[i] &= mask;
	buffer[i] |= color;
}

void Graphics::fillRect (int x, int y, int w, int h, uint32_t mask, uint32_t color) {
	for (int yp = y; yp < y + h; ++yp) {
		for (int xp = x; xp < x + w; ++xp) {
			plot(xp, yp, mask, color);
		}
	}
}

void Graphics::drawRect (int x, int y, int w, int h, uint32_t mask, uint32_t color) {
	for (int yp = y; yp < y + h; ++yp) {
		plot(x, yp, mask, color);
		plot(x + w - 1, yp, mask, color);
	}
	for (int xp = x + 1; xp < x + w - 1; ++xp) {
		plot(xp, y, mask, color);
		plot(xp, y + h - 1, mask, color);
	}
}

void Graphics::drawText (int x, int y, const std::string& text, uint32_t mask, uint32_t color) {
	int xpos = x;
	int ypos = y;
	for (const char& c : text) {
    	if (c >= 0 && c < 0x80) {
			if (c == 0xa) {
				xpos = x;
				ypos += 20;
			} else if (c == 0xd) {
			} else {
				unsigned char* bitmap = font8x8_basic[c];
				for (int cy = 0; cy < 8; ++cy) {
					unsigned char rowBits = bitmap[cy];
					for (int cx = 0; cx < 8; ++cx) {
						if ((rowBits & 0x01) > 0) {
							fillRect (xpos + cx * 2, ypos + cy * 2, 2, 2, mask, color);
						}
						rowBits >>= 1;
					}
				}
				xpos += 16;
			}			
		}
	}
}
